#ifndef SSM_H
#define SSM_H 
/*
* ssm.h
* Sunseker modelling (solar car preformance modelling) project
* include file for structures and routines.
*/
#define VERSION_ROUTE "0.6"

#define SIZE_VERSION 21
#define SIZE_COMMENT 201
#define SIZE_UNITS   21


//
// Race Route structures and read/write functions
//
// XX add double C_r;        // road condition
typedef struct {
  int    i;              	// just a check for input files.
  double distance;       	// distance of the leg, or perhaps better of the route so far. (M)
  double latitude;       	// units?
  double longitude;      	//
  double altitude;       	// for E_potential                                   (M)
  double speed_limit;    	// do we also need a speed min?                      (M/S)
  double speed;
  double stops;          	// stop factor, for now 1.0 means a stop at the end of leg
  double hills;          	// hill factor for hilly terrain, used later
  double shade;          	// shade factor, for P_array, used later
  double d_x, d_y, d_z;  	// direction of leg, local coordinates, for D_a with a wind.
  double windspeed;		//windspeed in m
  double windheading;		//wind heading
  double suntime;		//if a stop is present, this is how long to stop and sun, on array
} Leg;

typedef struct {
  char   version[SIZE_VERSION];   // Version of read_route/write_route and ssm.h
  char   comment[SIZE_COMMENT];   // Comment on this route.
  char   units[SIZE_UNITS];       // "metric" or "english"
  int    nleg;                    // The number of legs in this route
  Leg    *leg;                    // Array of nleg Leg structures.
  double targetBatt; //0-1
  double targetTime; //military time in seconds
} Route;

int read_route(const char *file, const char *plan_file, Route *route);
int write_route(const char *file, const Route *route);

//
// Race Car structure and read/write functions
// These are all constants for the cart.
// Later a more advanced version of A*C_d needs to be used, including wind direction.
//
typedef struct {
double A;          // Drag area (M^2)
double C_d;        // Drag coef.
double C_rr;       // Rolling resistance coef.
double W;          // Weight of car (N), varies a bit with alt, but ignore.
double M;          // Mass of car (KG)
double B_CHeff;	   // battery charge efficiency
double B_C;        // Battery Capacity (W S)
double B_CRate;    // Battery C rate for B_C capacity (W) (for mod. Peukert, should really be (I))
double B_CPeukert; // Battery Peukert coef. (modified Peukert 2.21, should really use 2.20)
double B_n;        // Battery Peukert number
double P_arrayMax; // Array power under 1 solar condition (W)
double M_d;        // motor and controller drive efficency, % at crusing speed and power
double M_r;        // motor and controller regen efficency, % at crusing speed and power
double P_p;        // parisitic power loss (W)
double accR;		//acceleration in m/s*s
double decelR;		//deceleration in m/s*s
/*should add deceleration rates for coasting, regen, and breaks,for now assume decelR is regen*/
} Car;

//
// Race Race structures and read/write functions
//
//  date, time_start time_stop, distance / leg to start on, battery_charge_start
typedef struct {
	double time_start;
	double time_stop;
} Race;

//
// Race Control and read/write functions
//
//control.dat
//  control of the car durring a race.
//  This file needs to be worked out. Lines such as
//     distance speed
//  which indicates when are at distance along the race, chang to speed,
//  need to be there...
//  Control of
//    speed                 cruse control
//    battery drain         accellerator control
//    coasting              (battery drain == 0)
//    regen
//    brakes
//  should be considered for inclusion... 
//  perhap linits on the rate of changes of these controls also.
//  if we ever model tempreture, then adding in fan control
//  for motor/controllea/MPPT cooling could be added.
typedef struct {
	int placeholder;
} Control;

//
// Race Simulation structure and read/write functions
//
//simulation.dat
//  time_step_sizes
//  output file name
//  output frequency
//  output format
typedef struct {
	double dt; 		//size of a time step in sec
	double t; 		//present time in sec
	int imax;  		//number of time steps to take
	int iprint;		//steps between output printing
	double stoptime; 	//time spent at end of leg;
	double speedOld;	//used to calculate KE change
	double speedNew; 	//used to calculate KE change
	double tDist;		//target distance up to and including the target leg
	double Btime;		//time to perform break manuiver at end of leg
	double Bdistance;	//distance to perform that break
} Simulation;

//
// Race Weather structure and read/write functions
//
//weather.dat
//  Weather is an open question. Controllingt either a linear time or space
//  sequence is direct. However, weather changes with both time and space.
//  From that perspective, a 2 dimensional data set is needed, both tme and space.
//       w_0,0 w_0,1 w_0,2 ... w_0,m
//       w_1,0 w_1,1 w_1,2 ... w_1,m
//       w_2,0 w_2,1 w_2,2 ... w_2,m
//        ...
//       w_n,0 w_n,1 w_n,2 ... w_n,m
//   where w_i,j is the weather at distance d_i and time t_j.
//   Perhaps a simpler model to start... only vary with time or position.
//   Weather includes:
//     cloud cover
//     wind velocity (direction and magnitude)
//     tempreture
//     barometric pressure
//     rain
//
// double rho;        // density of air (Kg / M^3) ... XXX compute this from pressure, temp ...
typedef struct {
	double rho;        // Current density of air (KG / M^3 )
	double sun_rise;   // 24 hour clock (S)	
	double sun_set;    // 24 hour clock (S)	
	double sun_length; // sun_set - sun_rise (S)
	double phi_n;      // sun angle from vertical at noon. (Rad)
	double phi;	   // sun angle from vertical at time t (Rad)
	double theta;      // array angle to sun (Rad)
	double winds;	   // wind speed in m/s
	double windd;      // wind direction in rad
	double CloudCover; // percent of energy lost due to cloud cover
} Weather;

// A D structure holds the weather/raod/race/car conditions that change "D"ynamically
// over each leg of the race.
typedef struct {
double D_a;     // aerodynamic drag (N)
double P_a;     // aerodynamic power (W = N M / S)
double E_a;     // aerodynamic energy (J = W * S = N M / S * S)
double D_rr;    // rolling resistance (N)
double P_rr;    // rolling power (W = N M / S)
double E_rr;    // rolling energy (J = W S)
double B_charge;// Battery charge used so far, between 0.0 and 1.0 (W S)
double P_array; // array power (W)
double E_array; // array energy (W S)
double P_p;     // parasitic power losses (W)
double E_p;     // parasitic energy losses (W S)
double E_charge;// Battery charge, between 0,0 and 1.0
double E_k;	// change in kinetic energy
double F_g;     // Force of gravity, in direction of travel (N)
double P_g;     // Power from change in gravational potential energy. (W = N M / S)
double E_g;     // Energy from change in gravational potential energy. (J = W S)
double P[3];    // position (M)          , Not used
double D[3];    // direction unit vector , Not used. velocity = speed * D
double A[3];    // accelleration (M/S^2) , Not used
double distance;// distance travelled (M)
double speed;   // speed (M/S)
double airspeed;
double a;       // accelleration (M / S^2)
double latitude;// GPS position
double longitude;//
double heading; //deg E from N
double h;       // altitude (M)

//the following are here temporarly
double P_drive;    // power needed to drive at speed
double E_drive;    // energy needed to drive at speed
double P_battery;  // power from battery to drive at speed 
double E_battery;  // energy from battery to drive at speed 
double B_capacity; // capacity at current power draw.
double DB_charge;  // change in battery charge at current power draw
double ddistance;  // distance traveled in the time step.
} Dynamic;

// Eats white space and "#" comments for the raed_* functions
// Also keeps track of the current input line.
// int eat_comment(FILE *fp, int *line);
//
//New functions by Ian
void printSim(Simulation source);
int writeSim(char* filename, Simulation *source);
int readSim(char* filename, Simulation *dest);

void printRace(Race source);
int writeRace(char* filename, Race *source);
int readRace(char* filename, Race *dest);

void printCar(Car source);
int writeCar(char* filename, Car *source);
int readCar(char* filename, Car *dest);

void printControl(Control source);
int writeControl(char* filename, Control *source);
int readControl(char* filename, Control *dest);

void printWeather(Weather source);
int writeWeather(char* filename, Weather *source);
int readWeather(char* filename, Weather *dest);

void printDynamic(Dynamic source);
int writeDynamic(char* filename, Dynamic *source);
int readDynamic(char* filename, Dynamic *dest);

//function in modeling.c
void printTitle(Race race, Simulation sim, Dynamic d, Weather weather, Car c);
void printStat(Race race, Simulation sim, Dynamic d, Weather weather);
int initializeSimulation(double speed, Race *race, Simulation *sim, Dynamic *d, Car *c, Weather *weather);
int initializeLeg(Race *race, Simulation *sim, Dynamic *d, Car *c, Weather *weather, Leg *leg, Route *route, int loopPos);


int modelControl(Dynamic *d);
int modelAero(Simulation sim, Dynamic *d, Car c, Weather weather);
int modelRollingR(Simulation sim, Dynamic *d, Car c);
int modelArray(Simulation sim, Dynamic *d, Car c, Weather *weather);
int modelParisitic(Simulation sim, Dynamic *d, Car c);
int modelKE(Simulation *sim, Dynamic *d, Car *c, Weather *weather, Route route, int loopPos, double speedOld, double speedNew);
int modelPE(Simulation sim, Dynamic *d, Car c, Leg legStart, Leg legFinish);
int modelBreaking();
int modelEnergy(Simulation sim, Dynamic *d, Car c);
int modelMotor(Dynamic *d, Car c);
int modelBatteryCharge(Simulation sim, Dynamic *d, Car c);

int simLoop(Race *race, Simulation *sim, Dynamic *d, Car *c, Weather *weather);
int routeLoop(Race *race, Simulation *sim, Dynamic *d, Car *c, Weather *weather, Route *route);
int modelSolpos(Simulation sim, Weather *weather, Leg leg);
int findHeading(Dynamic *d, Leg legStart, Leg legFinish);
int model(Simulation *sim, Dynamic *d, Car *c, Weather *weather, Route route, int loopPos);
void printHeader();
int logData(Dynamic d, Simulation sim);
int plotIze();

#endif
